/**
 * CurrencyCleaner - 金额清洗工具
 * 将各种金额格式统一为数字
 */

class CurrencyCleaner {
    /**
     * 清洗金额值，统一输出为数字
     * @param {string|number} value - 输入值
     * @param {Object} options - 配置选项
     * @param {number} options.decimals - 保留小数位数，默认2
     * @returns {number|null} 清洗后的数字，无法解析返回null
     */
    static clean(value, options = {}) {
        const { decimals = 2 } = options;

        if (value === null || value === undefined || value === '') {
            return null;
        }

        // 如果已经是数字
        if (typeof value === 'number') {
            return this._round(value, decimals);
        }

        // 字符串处理
        if (typeof value === 'string') {
            const result = this._parseString(value.trim());
            if (result !== null) {
                return this._round(result, decimals);
            }
        }

        console.warn(`[CurrencyCleaner] Unable to parse: ${value}`);
        return null;
    }

    /**
     * 解析金额并返回详细信息
     * @param {string|number} value - 输入值
     * @returns {Object} { value: number, type: 'credit'|'debit'|'unknown', original: string }
     */
    static parse(value) {
        const cleaned = this.clean(value);

        if (cleaned === null) {
            return { value: null, type: 'unknown', original: value };
        }

        // 判断借贷类型
        let type = 'unknown';
        if (typeof value === 'string') {
            const str = value.trim().toLowerCase();
            if (str.includes('借') || str.includes('支') || str.includes('付') || str.startsWith('-') || str.startsWith('(')) {
                type = 'debit';  // 支出/借方
            } else if (str.includes('贷') || str.includes('收') || str.includes('入')) {
                type = 'credit'; // 收入/贷方
            }
        }

        return {
            value: Math.abs(cleaned),
            type,
            original: value
        };
    }

    /**
     * 验证是否为有效金额
     * @param {string|number} value
     * @returns {boolean}
     */
    static isValid(value) {
        return this.clean(value) !== null;
    }

    /**
     * 解析字符串金额
     */
    static _parseString(str) {
        // 处理空白和特殊字符
        let cleaned = str;

        // 移除货币符号
        cleaned = cleaned.replace(/[¥$€£￥]/g, '');

        // 移除"元"、"圆"等单位
        cleaned = cleaned.replace(/[元圆角分]/g, '');

        // 移除千分位逗号
        cleaned = cleaned.replace(/,/g, '');

        // 处理中文数字单位
        cleaned = this._handleChineseUnits(cleaned);

        // 处理括号表示负数: (1234.56) -> -1234.56
        if (/^\([\d.]+\)$/.test(cleaned)) {
            cleaned = '-' + cleaned.replace(/[()]/g, '');
        }

        // 处理借贷标记
        if (/^借\s*/.test(cleaned)) {
            cleaned = '-' + cleaned.replace(/^借\s*/, '');
        } else if (/^贷\s*/.test(cleaned)) {
            cleaned = cleaned.replace(/^贷\s*/, '');
        }

        // 处理支/付/出 标记（通常表示支出）
        if (/^[支付出]\s*/.test(cleaned)) {
            cleaned = '-' + cleaned.replace(/^[支付出]\s*/, '');
        }

        // 处理收/入 标记（通常表示收入）
        if (/^[收入]\s*/.test(cleaned)) {
            cleaned = cleaned.replace(/^[收入]\s*/, '');
        }

        // 移除空格和其他非数字字符（保留负号和小数点）
        cleaned = cleaned.replace(/[^\d.\-]/g, '').trim();

        // 处理多个负号
        const isNegative = (cleaned.match(/-/g) || []).length % 2 === 1;
        cleaned = cleaned.replace(/-/g, '');

        // 验证格式
        if (!/^\d+(\.\d+)?$/.test(cleaned)) {
            return null;
        }

        const num = parseFloat(cleaned);
        return isNegative ? -num : num;
    }

    /**
     * 处理中文数字单位（万、亿）
     */
    static _handleChineseUnits(str) {
        // 匹配: 100万, 1.5亿, 10万元
        let result = str;

        // 处理"亿"
        const yiMatch = result.match(/^([\d.]+)\s*亿/);
        if (yiMatch) {
            const num = parseFloat(yiMatch[1]) * 100000000;
            result = num.toString() + result.substring(yiMatch[0].length);
        }

        // 处理"万"
        const wanMatch = result.match(/^([\d.]+)\s*万/);
        if (wanMatch) {
            const num = parseFloat(wanMatch[1]) * 10000;
            result = num.toString() + result.substring(wanMatch[0].length);
        }

        // 处理"千"
        const qianMatch = result.match(/^([\d.]+)\s*千/);
        if (qianMatch) {
            const num = parseFloat(qianMatch[1]) * 1000;
            result = num.toString() + result.substring(qianMatch[0].length);
        }

        return result;
    }

    /**
     * 四舍五入到指定小数位
     */
    static _round(num, decimals) {
        const factor = Math.pow(10, decimals);
        return Math.round(num * factor) / factor;
    }

    /**
     * 格式化金额为显示字符串
     * @param {number} value - 数字
     * @param {Object} options - 配置选项
     * @returns {string} 格式化后的字符串
     */
    static format(value, options = {}) {
        const {
            decimals = 2,
            thousandsSeparator = true,
            prefix = '',
            suffix = ''
        } = options;

        if (value === null || value === undefined || isNaN(value)) {
            return '';
        }

        let formatted = value.toFixed(decimals);

        if (thousandsSeparator) {
            const parts = formatted.split('.');
            parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
            formatted = parts.join('.');
        }

        return `${prefix}${formatted}${suffix}`;
    }
}

module.exports = CurrencyCleaner;
